package com.example.teaching_server.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 学生仪表板数据传输对象
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "学生仪表板数据")
public class StudentDashboardDTO {

    @NotNull(message = "工具列表不能为空")
    @Schema(description = "学习工具列表", requiredMode = Schema.RequiredMode.REQUIRED)
    private List<ToolDTO> tools;

    @NotNull(message = "资源列表不能为空")
    @Schema(description = "学习资源列表", requiredMode = Schema.RequiredMode.REQUIRED)
    private List<ResourceDTO> resources;

    @NotNull(message = "课堂活动列表不能为空")
    @Schema(description = "课堂活动列表", requiredMode = Schema.RequiredMode.REQUIRED)
    private List<ClassActivityDTO> classActivities;

    @NotNull(message = "证书列表不能为空")
    @Schema(description = "证书列表", requiredMode = Schema.RequiredMode.REQUIRED)
    private List<CertificateDTO> certificates;

    @NotBlank(message = "班级名称不能为空")
    @Schema(description = "学生所在班级名称", example = "一年级一班", requiredMode = Schema.RequiredMode.REQUIRED)
    private String className;

    @Schema(description = "学生ID", example = "2024001")
    private String studentId;

    @Schema(description = "学生姓名", example = "张三")
    private String studentName;

    @Schema(description = "年级", example = "一年级")
    private String grade;

    @Schema(description = "统计数据")
    private DashboardStatsDTO stats;

    /**
     * 获取可用的工具数量
     */
    @Schema(description = "可用工具数量", accessMode = Schema.AccessMode.READ_ONLY)
    public int getAvailableToolsCount() {
        if (tools == null) return 0;
        return (int) tools.stream().filter(ToolDTO::getAvailable).count();
    }

    /**
     * 获取最新资源
     */
    @Schema(description = "最新资源", accessMode = Schema.AccessMode.READ_ONLY)
    public ResourceDTO getLatestResource() {
        if (resources == null || resources.isEmpty()) return null;
        return resources.stream()
                .findFirst()
                .orElse(null);
    }

    /**
     * 获取活动总数
     */
    @Schema(description = "活动总数", accessMode = Schema.AccessMode.READ_ONLY)
    public int getTotalActivities() {
        return classActivities != null ? classActivities.size() : 0;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "学习工具信息")
    public static class ToolDTO {

        @NotBlank(message = "工具名称不能为空")
        @Schema(description = "工具名称", example = "在线作业", requiredMode = Schema.RequiredMode.REQUIRED)
        private String name;

        @NotBlank(message = "工具图标不能为空")
        @Schema(description = "Element Plus图标名称", example = "Document", requiredMode = Schema.RequiredMode.REQUIRED)
        private String icon;

        @NotNull(message = "工具可用性不能为空")
        @Schema(description = "是否可用", example = "true", requiredMode = Schema.RequiredMode.REQUIRED)
        private Boolean available;

        @Schema(description = "路由路径", example = "/homework")
        private String route;

        @Schema(description = "工具描述", example = "在线完成和提交作业")
        private String description;

        @Schema(description = "是否为新功能", example = "false")
        @Builder.Default
        private Boolean isNew = false;

        /**
         * 获取工具状态文本
         */
        @Schema(description = "工具状态文本", accessMode = Schema.AccessMode.READ_ONLY)
        public String getStatusText() {
            return available ? "可用" : "维护中";
        }

        /**
         * 获取图标颜色
         */
        @Schema(description = "图标颜色", accessMode = Schema.AccessMode.READ_ONLY)
        public String getIconColor() {
            return available ? "#409EFF" : "#909399";
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "学习资源信息")
    public static class ResourceDTO {

        @NotNull(message = "资源ID不能为空")
        @Positive(message = "资源ID必须是正整数")
        @Schema(description = "资源唯一标识", example = "1", requiredMode = Schema.RequiredMode.REQUIRED)
        private Long id;

        @NotBlank(message = "资源标题不能为空")
        @Schema(description = "资源标题", example = "数学课件第一章", requiredMode = Schema.RequiredMode.REQUIRED)
        private String title;

        @NotBlank(message = "资源类型不能为空")
        @Schema(description = "资源类型", example = "pdf", allowableValues = {"pdf", "word", "video", "audio", "image"}, requiredMode = Schema.RequiredMode.REQUIRED)
        private String type;

        @JsonFormat(pattern = "yyyy-MM-dd")
        @Schema(description = "更新时间", example = "2023-10-15", requiredMode = Schema.RequiredMode.REQUIRED)
        private String updatedAt;

        @NotBlank(message = "资源分类不能为空")
        @Schema(description = "资源分类", example = "class", allowableValues = {"class", "subscription"}, requiredMode = Schema.RequiredMode.REQUIRED)
        private String category;

        @Schema(description = "资源URL", example = "/resources/1/download")
        private String url;

        @Schema(description = "文件大小", example = "2.5 MB")
        private String fileSize;

        @Schema(description = "下载次数", example = "150")
        private Integer downloadCount;

        /**
         * 获取类型图标
         */
        @Schema(description = "类型图标", accessMode = Schema.AccessMode.READ_ONLY)
        public String getTypeIcon() {
            return switch (type.toLowerCase()) {
                case "pdf" -> "Document";
                case "word" -> "Document";
                case "video" -> "VideoPlay";
                case "audio" -> "Headphone";
                case "image" -> "Picture";
                default -> "QuestionFilled";
            };
        }

        /**
         * 判断是否为课堂资源
         */
        @Schema(description = "是否为课堂资源", accessMode = Schema.AccessMode.READ_ONLY)
        public boolean isClassResource() {
            return "class".equals(category);
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "课堂活动信息")
    public static class ClassActivityDTO {

        @NotNull(message = "活动ID不能为空")
        @Positive(message = "活动ID必须是正整数")
        @Schema(description = "活动唯一标识", example = "1", requiredMode = Schema.RequiredMode.REQUIRED)
        private Long id;

        @NotBlank(message = "活动标题不能为空")
        @Schema(description = "活动标题", example = "数学作业通知", requiredMode = Schema.RequiredMode.REQUIRED)
        private String title;

        @NotBlank(message = "活动类型不能为空")
        @Schema(description = "活动类型", example = "notice", allowableValues = {"notice", "checkin", "practice", "contact"}, requiredMode = Schema.RequiredMode.REQUIRED)
        private String type;

        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        @Schema(description = "更新时间", example = "2023-10-15 14:30:00")
        private String updatedAt;

        @Schema(description = "活动内容")
        private String content;

        @Schema(description = "活动描述")
        private String description;

        @Schema(description = "通知类型名称", example = "作业通知")
        private String noticeTypeName;

        @Schema(description = "发送人姓名", example = "张老师")
        private String senderName;

        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        @Schema(description = "创建时间", example = "2023-10-15 10:00:00")
        private String createTime;

        @Schema(description = "是否已读", example = "false")
        @Builder.Default
        private Boolean read = false;

        @Schema(description = "是否重要", example = "false")
        @Builder.Default
        private Boolean important = false;

        /**
         * 获取活动类型中文名称
         */
        @Schema(description = "活动类型中文名称", accessMode = Schema.AccessMode.READ_ONLY)
        public String getTypeName() {
            return switch (type) {
                case "notice" -> "通知";
                case "checkin" -> "签到";
                case "practice" -> "练习";
                case "contact" -> "联系";
                default -> type;
            };
        }

        /**
         * 获取内容摘要
         */
        @Schema(description = "内容摘要", accessMode = Schema.AccessMode.READ_ONLY)
        public String getContentSummary() {
            if (content == null) return "";
            return content.length() > 50 ? content.substring(0, 50) + "..." : content;
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "证书信息")
    public static class CertificateDTO {

        @NotNull(message = "证书ID不能为空")
        @Positive(message = "证书ID必须是正整数")
        @Schema(description = "证书唯一标识", example = "1", requiredMode = Schema.RequiredMode.REQUIRED)
        private Long id;

        @NotBlank(message = "证书标题不能为空")
        @Schema(description = "证书标题", example = "优秀学生证书", requiredMode = Schema.RequiredMode.REQUIRED)
        private String title;

        @NotBlank(message = "证书类型不能为空")
        @Schema(description = "证书类型", example = "personal", allowableValues = {"personal", "class"}, requiredMode = Schema.RequiredMode.REQUIRED)
        private String type;

        @JsonFormat(pattern = "yyyy-MM-dd")
        @Schema(description = "颁发日期", example = "2023-06-15", requiredMode = Schema.RequiredMode.REQUIRED)
        private String date;

        @Schema(description = "证书描述", example = "表彰在数学竞赛中的优异表现")
        private String description;

        @Schema(description = "证书图片URL", example = "/certificates/1/image")
        private String imageUrl;

        @Schema(description = "证书编号", example = "CERT2023001")
        private String certificateNo;

        /**
         * 获取证书类型中文名称
         */
        @Schema(description = "证书类型中文名称", accessMode = Schema.AccessMode.READ_ONLY)
        public String getTypeName() {
            return "personal".equals(type) ? "个人证书" : "班级证书";
        }

        /**
         * 判断是否为近期证书（3个月内）
         */
        @Schema(description = "是否为近期证书", accessMode = Schema.AccessMode.READ_ONLY)
        public boolean isRecent() {
            try {
                LocalDate certDate = LocalDate.parse(date);
                LocalDate threeMonthsAgo = LocalDate.now().minusMonths(3);
                return !certDate.isBefore(threeMonthsAgo);
            } catch (Exception e) {
                return false;
            }
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "仪表板统计数据")
    public static class DashboardStatsDTO {

        @Schema(description = "完成作业数", example = "15")
        private Integer completedAssignments;

        @Schema(description = "待完成作业数", example = "3")
        private Integer pendingAssignments;

        @Schema(description = "平均成绩", example = "85.5")
        private Double averageScore;

        @Schema(description = "出勤率", example = "95.0")
        private Double attendanceRate;

        @Schema(description = "学习时长（小时）", example = "120.5")
        private Double studyHours;

        /**
         * 获取作业完成率
         */
        @Schema(description = "作业完成率", accessMode = Schema.AccessMode.READ_ONLY)
        public Double getAssignmentCompletionRate() {
            if (completedAssignments == null || pendingAssignments == null) return 0.0;
            int total = completedAssignments + pendingAssignments;
            return total > 0 ? (completedAssignments * 100.0 / total) : 0.0;
        }
    }
}
